Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: strip schema from sequence name #143

Closed

Conversation

fsateler
Copy link
Contributor

@fsateler fsateler commented Jan 6, 2021

sequence_name is shared across threads because it is stored in a class
ivar. This means that on threaded servers, the sequence_name might point
to a different tenant, if another tenant made the switch at the right
time. This race is likely the cause of #81 as well.

This reverts commit f8eefc4.

Comment on lines +12 to +16
require 'active_record/connection_adapters/postgresql_adapter'

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
include Apartment::PostgreSqlAdapterPatch
end
Copy link
Contributor Author

@fsateler fsateler Jan 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is of course super ugly, and will crash when pg is not available, but I didn't know how to only patch this when postgresql is in use. Guidance appreciated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this i think we could require only when loading the postgresql schema adapter.
That being said, shouldn't we at this point simply make use of the active record reset_schema_name method when switching tenant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with reset_sequence_name is twofold:

  1. It goes to the db to find it https://github.com/rails/rails/blob/ecbd92cf48c741f784c1297041d368c8eb14e9bf/activerecord/lib/active_record/model_schema.rb#L357-L360.
  2. Modifying the sequence name is not hread safe: Postgres sequence_name correction is not thread safe  #161

Thus I believe the safest fix is to actually remove the schema from the sequence name

def default_sequence_name(table, _column)
res = super
schema_prefix = "#{Apartment::Tenant.current}."
if res.starts_with?(schema_prefix) && Apartment.excluded_models.none?{|m| m.constantize.table_name == table}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should check Apartment.use_schemas here. Is that flag still supported?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flag is still in place and i don't recall having changed anything around this, so we can most likely rely on it

@fsateler
Copy link
Contributor Author

fsateler commented Jan 6, 2021

sequence_name is shared across threads because it is stored in a class
ivar. This means that on threaded servers, the sequence_name might point
to a different tenant, if another tenant made the switch at the right
time. This race is likely the cause of
rails-on-services#81 as well.

This reverts commit f8eefc4.
@thibaudgg
Copy link

Hey @jgigault, any plan to merge this? We are also still seeing the #81 error with apartment 2.9.0 (and Rails 6.1).

@@ -121,11 +127,9 @@
it 'connects and resets' do
subject.switch(schema1) do
expect(connection.schema_search_path).to start_with %("#{schema1}")
expect(User.sequence_name).to eq "#{schema1}.#{User.table_name}_id_seq"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there anything particularly wrong with this test? Shouldn't these assumptions still be valid?

Copy link
Contributor

@rpbaltazar rpbaltazar Sep 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, after starting to make some tests with my codebase and looking at the changes made, I now understand.
The previous changes tried to fix this issue, but ended up introducing other bugs while fixing this problem.
So, please correct me if i'm wrong, but i think we'll need to merge these changes, that will revert the state to "broken".
Release 2.9.1.

Then we can merge the changes i'm suggesting in #169 (assuming it looks ok), document the apartment model logic and release the 3.0.0.
Agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this PR solves the problem better, because default_sequence_name involves a trip to the database.

Copy link
Contributor

@rpbaltazar rpbaltazar Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I did a couple of tests and as long as we have the correct search path set, it should be ok and we should be getting the correct sequence. Let's go ahead w your solution.

I still think that having the logic on a concern that we include in our models would be a simpler solution than trying to manage this changes only when using postgres

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think that having the logic on a concern that we include in our models would be a simpler solution than trying to manage this changes only when using postgres

I'd be willing to explore that but I'm not sure exactly what you have in mind. Do you mean something we extend into ActiveRecord::Base?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially something along these lines: https://github.com/rails-on-services/apartment/pull/169/files#diff-19a1d0c8bf6f60ce84cd210d933378fb77dd60a56232b05b0d2b89c1979c6331R8

I've adjusted the PR to follow your approach but with what i was suggesting

@rpbaltazar
Copy link
Contributor

Closing this in favor of #187

Thank you @fsateler for the work. I've used most of your changes to open that PR

@rpbaltazar rpbaltazar closed this Feb 2, 2022
@fsateler fsateler deleted the bugfix/sequence-name branch May 28, 2024 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants